import rrdtool
import os.path
import os
from service.PlusterLog import PlusterLog
from service.pconfig import PConfig
from service.exception import *

class Rrd(PlusterLog):
    "Round Robin database interface"
    tool=None
    def __init__(self):
        PlusterLog.__init__(self)
        self.rrd_path=None
        self._read_config()
        Rrd.tool=self

    def _read_config(self):
        "Read RRD config file"
        cfg=PConfig.attribute
        self.rrd_path=cfg.rrd_path
        self.rrd_png=self.rrd_path+"""png/"""
        #Since PConfig will guarantee rrd_path exists. I remove except here

    def create_node(self,name):
        """create standard rrd for node.5min one sample. 12/hour
        24/day 31/week once/week. total 3 months
        name= host name"""
        rrd=self.rrd_path+name+".rrd"
        if not os.path.exists(rrd):
            self.log.info("Create new rrd file: %s"%rrd)
            result=rrdtool.create(rrd,"DS:cpu:GAUGE:600:0:100","DS:mem:GAUGE:600:0:100","DS:in:COUNTER:600:U:U","DS:out:COUNTER:600:U:U",\
                           "RRA:AVERAGE:0.5:1:24","RRA:AVERAGE:0.5:12:24","RRA:AVERAGE:0.5:288:31","RRA:AVERAGE:0.5:2016:12")
            return result

    def remove_node (self, name):
        """ remove node rrd file"""
        rrd=self.rrd_path+name+".rrd"
        os.remove(rrd)

    def create_user(self,name):
        """create standard rrd for user to record it's cpu mem and
        number of node he used.
        name = user name
        If user rrd file already exists, do nothing."""
        rrd=self.rrd_path+name+".rrd"
        if not os.path.exists(rrd):
            self.log.info("Create new rrd file: %s"%rrd)
            result=rrdtool.create(rrd,"DS:cpu:GAUGE:600:0:100","DS:mem:GAUGE:600:0:100","DS:num:GAUGE:600:0:U",\
                           "RRA:AVERAGE:0.5:1:24","RRA:AVERAGE:0.5:12:24","RRA:AVERAGE:0.5:288:31","RRA:AVERAGE:0.5:2016:12")
            return result

    def remove_user (self, name):
        """ remove user rrd file"""
        rrd=self.rrd_path+name+".rrd"
        os.remove(rrd)

    def draw_node(self,name,start,end,size):
        """draw cpu mem receive transmit png for node
        name=host name
        start=start time(at format)
        end=end time(at format)
        size= full or ico """
        png=self.rrd_png+name
        rrd=self.rrd_path+name+".rrd"
        if not os.path.exists(rrd):
            self.log.error("Not exist %s. Can not draw"%rrd)
            raise RrdFileNotFoundError(rrd)
        if size=="full":
            self.log.debug("Create %s %s from %s"%(size,png,rrd))
            #Create CPU png
            title="-t Node: %s CPU Usage"%name
            ds="""DEF:c=%s:cpu:AVERAGE"""%rrd
            line="AREA:c#ff0000"
            cpu_png=png+"_cpu.png"
            rrdtool.graph(cpu_png,"-s %s"%start,"-e %s"%end,title,\
                          "-u 100","-l 0",ds,line)
            #Create MEM png
            title="-t Node: %s Memory Usage"%name
            ds="""DEF:c=%s:mem:AVERAGE"""%rrd
            line="AREA:c#00ff00"
            mem_png=png+"_mem.png"
            rrdtool.graph(mem_png,"-s %s"%start,"-e %s"%end,title,\
                          "-u 100","-l 0",ds,line)
            #Create in png
            title="-t Node: %s Net Receive Speed"%name
            ds="""DEF:c=%s:in:AVERAGE"""%rrd
            line="AREA:c#0000ff"
            i_png=png+"_in.png"
            rrdtool.graph(i_png,"-s %s"%start,"-e %s"%end,title,\
                          ds,line)
            #Create out png
            title="-t Node: %s Net Transmit Speed"%name
            ds="""DEF:c=%s:out:AVERAGE"""%rrd
            line="AREA:c#0000ff"
            out_png=png+"_out.png"
            rrdtool.graph(out_png,"-s %s"%start,"-e %s"%end,title,\
                          ds,line)
        elif size=="icon":
            #Create small ICON
            ico=png+"_ico.png"
            ds="""DEF:c=%s:cpu:AVERAGE"""%rrd
            ds1="""DEF:m=%s:mem:AVERAGE"""%rrd
            line="LINE2:c#ff0000"
            line1="LINE2:m#00ff00"
            rrdtool.graph(ico,"-s %s"%start,"-e %s"%end,\
                          "-u 100","-l 0","-j","-w 50","-h 49",\
                          ds,ds1,line,line1)


    def draw_user(self,name,start,end):
        """draw a png log for node
        name=user name
        start=start time
        end=end time"""
        png=self.rrd_png+name
        rrd=self.rrd_path+name+".rrd"
        if not os.path.exists(rrd):
            raise RrdNoUserError(rrd)
        title="-t User: %s Total CPU Usage"%name
        ds="""DEF:c=%s:cpu:AVERAGE"""%rrd
        line="AREA:c#ff0000"
        cpu_png=png+"_cpu.png"
        rrdtool.graph(cpu_png, "-s %s" % start, "-e %s" % end, title,
                      ds, line)
        #Create MEM png
        title="-t User: %s Memory Usage"%name
        ds="""DEF:c=%s:mem:AVERAGE"""%rrd
        line="AREA:c#00ff00"
        mem_png=png+"_mem.png"
        rrdtool.graph(mem_png, "-s %s" % start, "-e %s" % end, title,
                      ds, line)
        #Create login node number png
        title="-t User: %s Using Node Number"%name
        ds="""DEF:c=%s:num:AVERAGE"""%rrd
        line="AREA:c#00ff00"
        num_png=png+"_num.png"
        rrdtool.graph(num_png, "-s %s" % start, "-e %s" % end, title,
                      ds, line)



    def update_node(self,name,cpu,mem,i,o):
        """update node rrd file
        name=host name
        cpu,mem,i,o=int"""
        rrd=self.rrd_path+name+".rrd"
        if os.path.exists(rrd):
            #self.log.debug("update %s cpu %f mem %f in %s out %s"%(rrd,cpu,mem,i,o))
            rrdtool.update(rrd,"N:%f:%f:%s:%s"%(cpu,mem,i,o))
        else:
            self.log.error("Can not find %s file to update"%rrd)
            raise RrdFileNotFoundError(rrd)


    def update_user(self,name,cpu,mem,num):
        """update user rrd file"""
        rrd=self.rrd_path+name+".rrd"
        if os.path.exists(rrd):
            #self.log.debug("update %s cpu %f mem %f number of node %d"%(rrd,cpu,mem,num))
            rrdtool.update(rrd,"N:%f:%f:%d"%(cpu,mem,num))
        else:
            self.log.error("Can not find %s file to update"%rrd)
            raise RrdNoUserError(rrd)




